﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Resources;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Domain.Core;
using System.Data;

namespace Cesave.Domain.PermisosModule.Contracts.Juntas
{
	/// <summary>
	/// 
	/// </summary>
	public class JuntaService
		: IJuntaService
	{
		#region Private properties

		private readonly IJuntaRepository _juntaRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaRepository"></param>
		public JuntaService(IJuntaRepository juntaRepository)
		{
			if (juntaRepository == null)
				throw new ArgumentNullException("juntaRepository", Messages.exception_DependenciesAreNotInitialized);
			_juntaRepository = juntaRepository;
		}

		#endregion

		#region IJuntaService Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estadoGuid"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByEstado(Guid estadoGuid)
		{
			if (estadoGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByEstadoSpecification juntasByEstadoSpecification = new JuntasByEstadoSpecification(estadoGuid);
			return _juntaRepository.FindJuntasByEstadoSpecification(juntasByEstadoSpecification).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estadoGuid"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByEstadoAndStatus(Guid estadoGuid, bool status = true)
		{
			if (estadoGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByEstadoSpecification juntasByEstadoSpecification = new JuntasByEstadoSpecification(estadoGuid);
			return _juntaRepository.FindJuntasByEstadoAndStatusSpecification(juntasByEstadoSpecification, status).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoGuid"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByDistrito(Guid distritoGuid)
		{
			if (distritoGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByDistritoSpecification juntasByDistritoSpecification = new JuntasByDistritoSpecification(distritoGuid);
			return _juntaRepository.FindJuntasByDistritoSpecification(juntasByDistritoSpecification).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="distritoGuid"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByDistritoAndStatus(Guid distritoGuid, bool status = true)
		{
			if (distritoGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByDistritoSpecification juntasByDistritoSpecification = new JuntasByDistritoSpecification(distritoGuid);
			return _juntaRepository.FindJuntasByDistritoAndStatusSpecification(juntasByDistritoSpecification, status).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <returns></returns>
		public Junta FindJuntaByGuid(Guid juntaGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntaByGuidSpecification juntaByGuidSpecification = new JuntaByGuidSpecification(juntaGuid);
			return _juntaRepository.FindJuntaByGuidSpecification(juntaByGuidSpecification);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="junta"></param>
		public void AddJunta(Junta junta)
		{
			if (junta == null)
				throw new ArgumentNullException("junta", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _juntaRepository.StoreContext;
			_juntaRepository.Add(junta);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="junta"></param>
		public void ChangeJunta(Junta junta)
		{
			if (junta == null)
				throw new ArgumentNullException("junta", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _juntaRepository.StoreContext;
			_juntaRepository.Modify(junta);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="junta"></param>
		public void DeleteJunta(Junta junta)
		{
			if (junta == null)
				throw new ArgumentNullException("junta", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _juntaRepository.StoreContext;
			_juntaRepository.Remove(junta);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="junta"></param>
		public void ActivateJunta(Junta junta)
		{
			if (junta == null)
				throw new ArgumentNullException("junta", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _juntaRepository.StoreContext;
			junta.Status = true;
			_juntaRepository.Modify(junta);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="junta"></param>
		public void DeactivateJunta(Junta junta)
		{
			if (junta == null)
				throw new ArgumentNullException("junta", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _juntaRepository.StoreContext;
			junta.Status = false;
			_juntaRepository.Modify(junta);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipioGuid"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByMunicipio(Guid municipioGuid)
		{
			if (municipioGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByMunicipioSpecification juntasByMunicipioSpecification = new JuntasByMunicipioSpecification(municipioGuid);
			return _juntaRepository.FindJuntasByMunicipioSpecification(juntasByMunicipioSpecification).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipioGuid"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public List<Junta> FindJuntasByMunicipioAndStatus(Guid municipioGuid, bool status = true)
		{
			if (municipioGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			JuntasByMunicipioSpecification juntasByMunicipioSpecification = new JuntasByMunicipioSpecification(municipioGuid);
			return _juntaRepository.FindJuntasByMunicipioAndStatusSpecification(juntasByMunicipioSpecification, status).ToList();
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_juntaRepository != null &&
				_juntaRepository.StoreContext != null)
				_juntaRepository.StoreContext.Dispose();
		}

		#endregion
	}
}
